﻿using KAs.Application.Contract.Dto;
using KAs.Application.Contract.Svc;
using KAs.Cache;
using KAs.Common.Attr;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions;
using Microsoft.Extensions.DependencyInjection;

namespace KAs.Filter;

/// <summary>
/// 已在startup中注册至所有action，非鉴权接口应添加特性AllowAnonymousFilter
/// </summary>
public class ApiAuthorFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        if (context.ActionDescriptor.EndpointMetadata.Any(x => x.GetType() == typeof(AllowAnonymousAttribute)))
            return;

        var cache = context.HttpContext.RequestServices.GetService<ICache>();
        // 初始化当前用户服务，该服务在项目启动时被注册为scope服务，每次请求唯一
        var currentUserInfo = context.HttpContext.RequestServices.GetService<ICurrentUserInfo>();
        if (!context.HttpContext.Request.Headers.ContainsKey("Authorization"))
        {
            context.Result = new JsonResult(ApiResult<string>.IsError("当前请求未授权", code: "401")) { StatusCode = 401 };
            return;
        }

        var token = context.HttpContext.Request.Headers["Authorization"].ToString();
        var tokenUserInfo = cache.GetToken(token);
        if (tokenUserInfo == null)
        {
            context.Result = new JsonResult(ApiResult<string>.IsError("未登录或登录超时，请重新登录", code: "401")) { StatusCode = 401 };
            return;
        }
        else
        {
            // 管理员访问接口判断
            if (context.ActionDescriptor.EndpointMetadata.Any(x => x.GetType() == typeof(OnlyAdminAttribute)) && !tokenUserInfo.IsAdmin)
                return;
            // 将token中获取的用户信息设置为当前用户信息
            tokenUserInfo.Token = token;
            currentUserInfo.SetUserInfo(tokenUserInfo);
            // 重置超时时间
            cache.RefreshToken(token);
        }
    }
}
